<?php
/**
 * Created by PhpStorm.
 * Author: 芸签cms www.yunqiancms.com
 * User: sun
 * Date: 2022/9/21
 * Time: 2:06 PM
 */
namespace app\backend\modules\common\services;

use app\common\exceptions\BizException;
use app\common\facades\Setting;
use app\common\models\CoreAttach;

class UploadService
{
    /**
     * @param $file \Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|array|null
     * @param $type
     * @param bool $saveAttach 数据是否保存到core_attach表
     * @return array
     * @throws BizException
     * @throws \OSS\Core\OssException
     */
    public function upload($file,$type,$saveAttach=true){
        //$file = request()->file('file');

        if (!$file) {
            throw new BizException('请传入正确参数.');
        }

        if (!$file->isValid()) {
            throw new BizException('上传失败.');
        }

        //$type = request()->upload_type;

        // 获取文件相关信息
        $originalName = $file->getClientOriginalName(); // 文件原名
        $realPath = $file->getRealPath();   //临时文件的绝对路径
        $ext = $file->getClientOriginalExtension(); //文件后缀

        $harmtype = array('asp', 'php', 'jsp', 'js', 'css', 'php3', 'php4', 'php5', 'ashx', 'aspx', 'exe', 'cgi');
        if (in_array($ext, $harmtype)) {
            throw new BizException('文件格式禁止上传');
        }
        $setting = Setting::get('cms.attach');
        $remote = Setting::get('cms.remote_attach');
        $storageName = 'files';
        $typeValue = CoreAttach::FILE_TYPE;
        if ($type == 'image') {
            if ($file->getSize() > 30 * 1024 * 1024) {
                throw new BizException('图片过大.');
            }

            $defaultImgType = [
                'jpg', 'bmp', 'eps', 'gif', 'mif', 'miff', 'png', 'tif',
                'tiff', 'svg', 'wmf', 'jpe', 'jpeg', 'dib', 'ico', 'tga', 'cut', 'pic','mp4'
            ];

            if (!in_array($ext, $defaultImgType)) {
                throw new BizException('非规定类型的文件格式');
            }

            if (!$ext) {
                $ext = 'jpg';
            }
            if (in_array($ext, $defaultImgType)) {
                if ($setting['pic_suffix'] && !in_array($ext, array_filter($setting['pic_suffix']))) {
                    throw new BizException('非规定类型的文件格式');
                }
                $defaultImgSize = $setting['pic_size'] ? $setting['pic_size'] * 1024 : 1024 * 1024 * 5; //默认大小为5M
                if ($file->getSize() > $defaultImgSize) {
                    throw new BizException('文件大小超出规定值');
                }
            }
            $storageName = 'images';
            $typeValue = CoreAttach::IMAGE_TYPE;
        } elseif ($type == 'video') {
            if ($file->getSize() > 50 * 1024 * 1024) {
                throw new BizException('资源过大.');
            }

            $defaultAudioType = ['avi', 'asf', 'wmv', 'avs', 'flv', 'mkv', 'mov', '3gp', 'mp4',
                'mpg', 'mpeg', 'dat', 'ogm', 'vob', 'rm', 'rmvb', 'ts', 'tp', 'ifo', 'nsv'
            ];

            $defaultVideoType = [
                'mp3', 'aac', 'wav', 'wma', 'cda', 'flac', 'm4a', 'mid', 'mka', 'mp2',
                'mpa', 'mpc', 'ape', 'ofr', 'ogg', 'ra', 'wv', 'tta', 'ac3', 'dts'
            ];

            $merge_ext = array_merge($defaultAudioType, $defaultVideoType);
            if (!in_array($ext, $merge_ext)) {
                throw new BizException('非规定类型的文件格式');
            }
            $storageName = 'videos';
            $typeValue = CoreAttach::VIDEO_TYPE;
        } elseif ($type == 'audio') {
            if ($file->getSize() > 50 * 1024 * 1024) {
                throw new BizException('资源过大.');
            }

            $defaultAudioType = ['avi', 'asf', 'wmv', 'avs', 'flv', 'mkv', 'mov', '3gp', 'mp4',
                'mpg', 'mpeg', 'dat', 'ogm', 'vob', 'rm', 'rmvb', 'ts', 'tp', 'ifo', 'nsv'
            ];

            $defaultVideoType = [
                'mp3', 'aac', 'wav', 'wma', 'cda', 'flac', 'm4a', 'mid', 'mka', 'mp2',
                'mpa', 'mpc', 'ape', 'ofr', 'ogg', 'ra', 'wv', 'tta', 'ac3', 'dts'
            ];

            $merge_ext = array_merge($defaultAudioType, $defaultVideoType);
            if (!in_array($ext, $merge_ext)) {
                throw new BizException('非规定类型的文件格式');
            }
            $storageName = 'audios';
            $typeValue = CoreAttach::AUDIO_TYPE;
        } elseif ($type == 'file') {
            if ($file->getSize() > 30 * 1024 * 1024) {
                throw new BizException('图片过大.');
            }

            //允许上传的文件,新添mp4格式
            $defaultImgType = [
                'jpg', 'bmp', 'eps', 'gif', 'mif', 'miff', 'png', 'tif',
                'tiff', 'svg', 'wmf', 'jpe', 'jpeg', 'dib', 'ico', 'tga', 'cut', 'pic','pdf','mp4'
            ];

            if (!in_array($ext, $defaultImgType)) {
                throw new BizException('非规定类型的文件格式');
            }

            if (!$ext) {
                throw new BizException('非规定类型的文件格式');
            }
            $storageName = 'files';
            $typeValue = CoreAttach::FILE_TYPE;
        }
        $newOriginalName = md5($originalName . str_random(6)) . '.' . $ext;
        //本地上传
        $result = \Storage::disk($storageName)->put($newOriginalName, file_get_contents($realPath));
        if (!$result) {
            throw new BizException('上传失败');
        }

        $url = \Storage::disk($storageName)->url($newOriginalName);
        if($saveAttach){
            CoreAttach::create([
                'site_id' => \YunCms::siteId(),
                'uid' => \YunCms::$adminUid,
                'filename' => safe_gpc_html(htmlspecialchars_decode($originalName, ENT_QUOTES)),
                'attachment' => $url,
                'type' => $typeValue,
                'upload_type' => $remote['type']
            ]);
        }

        //远程上传
        if ($remote['type'] != 0) {
            file_remote_upload($url, $remote, true);
        }
        return [
            'name' => $originalName,
            'ext' => $ext,
            'filename' => $newOriginalName,
            'attachment' => $url,
            'url' => fmt_media_url($url),
            'is_image' => 1,
            'filesize' => 'null',
            'state'     => 'SUCCESS'
        ];
    }


}